﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using SystemSettings;
using Labthink.PCSoft.UniversalHost4.DataAccess;
using Labthink.PCSoft.UniversalHost4.Model;
using Labthink.PCSoft.UniversalHost4.Model.User;
using Labthink.PCSoft.UniversalHost4.TcpCommands;
using Labthink.PCSoft.UniversalHost4.Utility;
using Newtonsoft.Json;
using Report.Model;
using FullData = Labthink.PCSoft.UniversalHost4.Model.FullData;

namespace Report
{
    public class ReportManager1
    {
        private readonly DataSet _ds;//报表数据源
        private DataSet _source;
        private readonly List<string> _files;//数据库文件
        private readonly Dictionary<string, string> _languages;
        private Dictionary<int, ReportConfig> _cfgs;
        public Dictionary<int, string> AddInputs;
        public List<Curve> Curves { get; private set; }
        public List<FullData> ParamInfo { get; private set; }
        public List<FullData> DataInfo { get; private set; }
        public List<FullData> ResultInfo { get; private set; }
        public List<SelectedData> ParamSelected { get; private set; }
        public List<SelectedData> DataSelected { get; private set; }
        public List<SelectedData> ResultSelected { get; private set; }

        private readonly ReportInfo _ri;

        private static ReportManager1 _manager;

        public List<UserPermission> Permissions { get; set; }

        //public ICommands Cmd { get; set; }

        public UserInfo User { get; set; }

        public int TypeId { get; set; }

        private int _type;

        public int Id { get; private set; }

        private double _lastTop = 4.94271;
        private const double CurveHeight = 11;

        private ReportManager1()
        {
            _languages = new Dictionary<string, string>();
            _ds = new DataSet();
            _files = new List<string>();
            Curves = new List<Curve>();
            ResultInfo = new List<FullData>();
            DataInfo = new List<FullData>();
            ParamInfo = new List<FullData>();
            ParamSelected = new List<SelectedData>();
            DataSelected = new List<SelectedData>();
            ResultSelected = new List<SelectedData>();
            _cfgs = new Dictionary<int, ReportConfig>();
            AddInputs = new Dictionary<int, string>();
            TypeId = 10033;
            _ri = new ReportInfo
            {
                Title = ReportCommon.GetLan.GetLanguageValue("TestReport"),
                Sign = "",
                UserInfo = "",
                Param = ReportCommon.GetLan.GetLanguageValue("TestParam"),
                Result = ReportCommon.GetLan.GetLanguageValue("TestResult"),
                DataCurve = ReportCommon.GetLan.GetLanguageValue("TestCurve"),
                DateList = ReportCommon.GetLan.GetLanguageValue("DataList"),
                ResultCurve = "",
                ResultList = ""
            };
        }

        public static ReportManager1 Create()
        {
            return _manager ??= new ReportManager1();
        }

        public void GetConfigs(List<ReportConfig> cfgs)
        {
            _cfgs = new Dictionary<int, ReportConfig>();
            foreach (var cfg in cfgs.Where(c => c.Type > 0))
            {
                _cfgs.Add(cfg.Type, cfg);
            }
        }

        public void SetNameAndLogo(string name, string logo)
        {
            if (!string.IsNullOrEmpty(name)) _ri.Title = name;
            if (!string.IsNullOrEmpty(logo)) _ri.Logo = logo;
        }

        public int SaveConfigAsync()
        {
            var cfg = new ReportConfig
            {
                Type = _type,
                Param = JsonConvert.SerializeObject(ParamSelected),
                Result = JsonConvert.SerializeObject(ResultSelected),
                DataList = JsonConvert.SerializeObject(DataSelected),
                DataCurve = JsonConvert.SerializeObject(Curves),
                ResultCurve = ""

            };
            var r = ReportConfigManager.UpdateConfig(cfg);
            if (r >= 0)
            {
                if (_cfgs.ContainsKey(_type))
                {
                    _cfgs[_type] = cfg;
                }
                else
                {
                    _cfgs.Add(_type, cfg);
                }
                AddInputs.Clear();
                foreach (var ps in ParamSelected.Where(p => !string.IsNullOrEmpty(p.Text)))
                {
                    //if (ParamInfo.All(d => d.DataNo != ps.Id))
                    {
                        AddInputs.Add(ps.Id, "");
                    }
                }
                foreach (var ps in ResultSelected.Where(p => !string.IsNullOrEmpty(p.Text)))
                {
                    //.Where(p=>!string.IsNullOrEmpty(p.Text))if (ResultInfo.All(d => d.DataNo != ps.Id))
                    {
                        AddInputs.Add(ps.Id, "");
                    }
                }

                Log(ReportCommon.GetLan.GetLanguageValue("ReportLogSaveConfig"));
            }
            return r;
        }

        public void Log(string log)
        {
            LogRepository.AddLog(log,"REPORT");
        }

        public int AddCurves(string title, bool isDrawPoint, Axis x, params Axis[] ys)
        {
            if (Curves.Any(d => d.Title == title)) return -1;
            var c = new Curve
            {
                X = x,
                Y = new List<Axis>(ys),
                Title = title,
                IsDrawPoint = isDrawPoint
            };
            var str = new StringBuilder();
            foreach (var y in ys)
            {
                str.Append(DataInfo.Single(d => d.DataNo == y.Id).Text).Append(",");
            }
            Curves.Add(c);
            Log(string.Format(ReportCommon.GetLan.GetLanguageValue("ReportLogAddCurve"), title, DataInfo.Single(d => d.DataNo == x.Id).Text, str.Remove(str.Length - 1, 1)));
            return 0;
        }

        public void AddFile(string file)
        {
            _files.Add(file);
            _initInfo();
        }

        public void AddInfo(string sign, string user)
        {
            _ri.Sign = sign;
            _ri.UserInfo = user;
        }

        public void Clear()
        {
            _files.Clear();
            _source = null;
            //ResultInfo.Clear();
            //DataInfo.Clear();
            //ParamInfo.Clear();
            //Curves.Clear();
        }

        public DataSet CreateReportData()
        {
            _ds.Clear();
            _ds.Tables.Clear();
            if (_source == null)
            {
                var sda = new SqliteDataAccess(_files[0]);
                _source = sda.GetAllData();
            }

            _createInfo();
            _createParam(_source);
            _createResult(_source);
            _createDataCurve(_source);
            _createData(_source);
            //_createDataList(_source);
            return _ds;
        }


        public void AddParam(string name, string value)
        {
            var max1 = ParamSelected.Max(p => p.Id);
            var max2 = ParamInfo.Max(p => p.DataNo);
            var id = Math.Max(max1, max2) + 1;
            ParamSelected.Add(new SelectedData { Id = id, Text = name });
            ParamInfo.Add(new FullData
            {
                DataNo = id,
                Text = name,
                Value = value,
                ColumnName = ""
            });
            Log(string.Format(ReportCommon.GetLan.GetLanguageValue("ReportLogAddParam"), name, value));
        }

        public void RemoveParams(List<int> removes)
        {
            if (removes == null)
            {
                _resetParam1();
                Log(ReportCommon.GetLan.GetLanguageValue("ReportLogResetParam"));
                return;
            }

            foreach (int remove in removes)
            {
                SelectedData p = ParamSelected.SingleOrDefault(ps => ps.Id == remove);
                if (p != null)
                {
                    ParamSelected.Remove(p);
                    Log(string.Format(ReportCommon.GetLan.GetLanguageValue("ReportLogRemoveParam"), ParamInfo.Single(d => d.DataNo == remove).Text));
                }
            }
        }

        private void _resetParam1()
        {
            ParamSelected.Clear();
            ParamInfo.RemoveAll(d => string.IsNullOrEmpty(d.ColumnName));
            foreach (FullData fd in ParamInfo)
            {
                ParamSelected.Add(new SelectedData { Id = fd.DataNo });
            }
        }

        public void SequenceParams(List<SelectedData> seqs)
        {
            if (seqs == null)
            {
                _resetParam2();
                return;
            }
            foreach (SelectedData seq in seqs)
            {
                SelectedData p = ParamSelected.SingleOrDefault(ps => ps.Id == seq.Id);
                if (p != null) p.Sequence = seq.Sequence;
            }
        }

        private void _resetParam2()
        {
            foreach (SelectedData fd in ParamSelected)
            {
                fd.Sequence = 0;
            }
        }

        public void AddResult(string name, string value)
        {
            var max1 = ResultSelected.Max(p => p.Id);
            var max2 = ResultInfo.Max(p => p.DataNo);
            var id = Math.Max(max1, max2) + 1;
            ResultSelected.Add(new SelectedData { Id = id, Text = name });
            ResultInfo.Add(new FullData
            {
                DataNo = id,
                Text = name,
                Value = value,
                ColumnName = ""
            });
            Log(string.Format(ReportCommon.GetLan.GetLanguageValue("ReportLogAddResult"), name, value));
        }

        public void RemoveResults(List<int> removes)
        {
            if (removes == null)
            {
                _resetResult1();
                Log(ReportCommon.GetLan.GetLanguageValue("ReportLogResetResult"));
                return;
            }

            foreach (int remove in removes)
            {
                SelectedData p = ResultSelected.SingleOrDefault(ps => ps.Id == remove);
                if (p != null)
                {
                    ResultSelected.Remove(p);
                    Log(string.Format(ReportCommon.GetLan.GetLanguageValue("ReportLogRemoveResult"), ResultInfo.Single(d => d.DataNo == remove).Text));
                }
            }
        }

        private void _resetResult1()
        {
            ResultSelected.Clear();
            ResultInfo.RemoveAll(d => string.IsNullOrEmpty(d.ColumnName));
            foreach (var fd in ResultInfo)
            {
                ResultSelected.Add(new SelectedData { Id = fd.DataNo });
            }
        }

        public void SequenceResults(List<SelectedData> seqs)
        {
            if (seqs == null)
            {
                _resetResult2();
                return;
            }
            foreach (var seq in seqs)
            {
                var p = ResultSelected.SingleOrDefault(ps => ps.Id == seq.Id);
                if (p != null) p.Sequence = seq.Sequence;
            }
        }

        public void PrecisionResults(List<SelectedData> seqs)
        {
            if (seqs == null)
            {
                _resetResult3();
                return;
            }
            foreach (var seq in seqs)
            {
                if (seq.Precision.HasValue)
                {
                    var p = ResultSelected.SingleOrDefault(ps => ps.Id == seq.Id);
                    if (p != null) p.Precision = seq.Precision;
                }
            }
        }

        private void _resetResult2()
        {
            foreach (SelectedData fd in ResultSelected)
            {
                fd.Sequence = 0;
            }
        }

        private void _resetResult3()
        {
            foreach (SelectedData fd in ResultSelected)
            {
                fd.Precision = null;
            }
        }

        public int RemoveCurve(string title)
        {
            var curve = Curves.SingleOrDefault(c => c.Title == title);
            if (curve == null) return -1;
            var r = Curves.Remove(curve) ? 1 : -1;
            if (r > 0)
                Log(string.Format(ReportCommon.GetLan.GetLanguageValue("ReportLogRemoveCurve"), title));
            return r;
        }

        public void SetDataList(List<SelectedData> sds)
        {
            DataSelected.Clear();
            if (sds != null) DataSelected.AddRange(sds);
        }

        private void _createInfo()
        {
            DataTable dt = _ds.Tables.Add("RI");
            Type t = typeof(ReportInfo);
            foreach (PropertyInfo pi in t.GetProperties())
            {
                dt.Columns.Add(pi.Name, pi.PropertyType);
            }

            var dr = dt.NewRow();
            foreach (PropertyInfo pi in t.GetProperties())
            {
                dr[pi.Name] = pi.GetValue(_ri, null);
            }
            dt.Rows.Add(dr);
        }

        private void _createParam(DataSet ds)
        {
            //参数
            var dt = _ds.Tables.Add("PT");
            var t = typeof(ParamTable);
            foreach (var pi in t.GetProperties())
            {
                dt.Columns.Add(pi.Name, pi.PropertyType);
            }
            var tmpParam = ParamInfo;
            if (ParamSelected.Count > 0)
            {
                //如果有用户选择的参数
                tmpParam = new List<FullData>();
                foreach (var ps in ParamSelected.OrderBy(p => p.Sequence))
                {
                    var pi = ParamInfo.SingleOrDefault(d => d.DataNo == ps.Id);
                    if (pi != null) tmpParam.Add(pi);
                    else if (AddInputs != null && AddInputs.ContainsKey(ps.Id))
                    {

                        tmpParam.Add(new FullData
                        {
                            DataNo = ps.Id,
                            Text = ps.Text,
                            Value = AddInputs[ps.Id],
                            ColumnName = ""
                        });
                    }
                }
            }
            //生成数据
            var index = 0;
            var dr = dt.NewRow();
            var param = ds.Tables[0];
            foreach (var tp in tmpParam)
            {
                var name = tp.Text;
                var value = tp.Value?.ToString() ?? "";

                if (param.Columns.Contains(tp.ColumnName))
                {
                    value = param.Rows[0][tp.ColumnName].ToString();
                    //数据库原值
                    if (tp.DataType != DataType.String)
                    {
                        if ((int)value.ToDouble() == -1)
                        {
                            value = "--";
                            continue;
                        }
                        else if (tp.DataType == DataType.Int)
                        {
                            if (_languages.ContainsKey(tp.LanguageId + value))
                                value = _languages[tp.LanguageId + value];
                        }
                        else if (tp.DataType == DataType.Double)
                        {
                            value = _round(value.ToDouble(), tp.Precision);
                        }
                        else if (tp.DataType == DataType.EDouble)
                        {
                            value = value.ToDouble().ScientificNotation(tp.Precision);
                        }
                    }
                    if (value == "-1")
                    {
                        value = "--";
                        continue;
                    }
                    else
                    {
                        if (!string.IsNullOrEmpty(value) && !string.IsNullOrEmpty(tp.Unit) && value != "--" && tp.Unit != "null")
                        {
                            value += "(" + tp.Unit + ")";
                        }
                    }
                }

                if (index % 2 == 0)
                {
                    dr["ParamName1"] = name;
                    dr["ParamValue1"] = value;
                }
                else
                {
                    dr["ParamName2"] = name;
                    dr["ParamValue2"] = value;
                    dt.Rows.Add(dr);
                    dr = dt.NewRow();
                }
                index++;
            }
            if (index % 2 != 0)
            {
                dt.Rows.Add(dr);
            }
        }

        private void _createResult(DataSet ds)
        {
            //参数
            var dt = _ds.Tables.Add("RT");
            var t = typeof(ResultTable);
            foreach (var pi in t.GetProperties())
            {
                dt.Columns.Add(pi.Name, pi.PropertyType);
            }
            var tmpParam = ResultInfo;
            if (ResultSelected.Count > 0)
            {
                //如果有用户选择的参数
                tmpParam = new List<FullData>();
                foreach (var ps in ResultSelected.OrderBy(p => p.Sequence))
                {
                    var pi = (FullData)ResultInfo.SingleOrDefault(d => d.DataNo == ps.Id).Clone();
                    if (pi != null)
                    {
                        if (ps.Precision.HasValue) pi.Precision = ps.Precision.Value;
                        tmpParam.Add(pi);
                    }
                    else tmpParam.Add(new FullData
                    {
                        DataNo = ps.Id,
                        Text = ps.Text,
                        Value = AddInputs[ps.Id],
                        ColumnName = ""
                    });
                }
            }

            //生成数据
            var index = 0;
            var dr = dt.NewRow();
            var param = ds.Tables[2];
            foreach (var tp in tmpParam)
            {
                var name = tp.Text;
                var value = tp.Value?.ToString() ?? "";

                if (param.Columns.Contains(tp.ColumnName))
                {
                    value = param.Rows[0][tp.ColumnName].ToString();
                    //数据库原值
                    if (tp.DataType != DataType.String)
                    {
                        if ((int)value.ToDouble() == -1) value = "--";
                        else if (tp.DataType == DataType.Int)
                        {
                            if (_languages.ContainsKey(tp.LanguageId + value))
                                value = _languages[tp.LanguageId + value];
                        }
                        else if (tp.DataType == DataType.Double)
                        {
                            value = _round(value.ToDouble(), tp.Precision);
                        }
                        else if (tp.DataType == DataType.EDouble)
                        {
                            value = value.ToDouble().ScientificNotation(tp.Precision);
                        }
                    }
                    if (value == "-1") value = "--";
                    else
                    {
                        if (!string.IsNullOrEmpty(tp.Unit) && value != "--" && tp.Unit != "null")
                        {
                            value += "(" + tp.Unit + ")";
                        }
                    }
                }

                if (index % 2 == 0)
                {
                    dr["ResultName1"] = name;
                    dr["ResultValue1"] = value;
                }
                else
                {
                    dr["ResultName2"] = name;
                    dr["ResultValue2"] = value;
                    dt.Rows.Add(dr);
                    dr = dt.NewRow();
                }
                index++;
            }
            if (index % 2 != 0)
            {
                dt.Rows.Add(dr);
            }
        }

        private void _createDataCurve(DataSet ds)
        {
            var dt = _ds.Tables.Add("CI");
            var param = ds.Tables[1];
            if (param.Rows.Count == 0) return;
            var t = typeof(CurveInfo);
            foreach (var pi in t.GetProperties())
            {
                dt.Columns.Add(pi.Name, pi.PropertyType);
            }
            ImageFactory.Clear();
            var index = 1;
            foreach (var curve in Curves)
            {
                var file = ImageFactory.GetReportImage(curve, DataInfo, param);
                var dr = dt.NewRow();

                dr["CurveName"] = string.IsNullOrEmpty(curve.Title) ? string.Format(ReportCommon.GetLan.GetLanguageValue("CurveNameSeq"), index) : curve.Title;
                dr["CurveFile"] = "file:///" + file;
                dt.Rows.Add(dr);
                index++;
            }
        }

        private void _createDataList(DataSet ds)
        {
            var dn = _ds.Tables.Add("DN");
            var t = typeof(DataListName);
            foreach (var pi in t.GetProperties())
            {
                dn.Columns.Add(pi.Name, pi.PropertyType);
            }
            if (DataSelected.Count == 0) return;


            var index = 1;
            var r = dn.NewRow();
            r["Dln"] = "No.";
            foreach (var fd in DataInfo)
            {
                if (index > 8) break;
                var str = fd.Text;
                if (!string.IsNullOrEmpty(fd.Unit) && fd.Unit != "null")
                {
                    str += " (" + fd.Unit + ")";
                }
                r["Dln" + index] = str;
                index++;
            }
            dn.Rows.Add(r);
        }

        private void _createData(DataSet ds)
        {
            var dt = _ds.Tables.Add("DL");
            var t = typeof(DataList);
            foreach (var pi in t.GetProperties())
            {
                dt.Columns.Add(pi.Name, pi.PropertyType);
            }

            var data = ds.Tables[1];
            foreach (DataRow dr in data.Rows)
            {
                var index = 1;
                var row = dt.NewRow();
                foreach (var fd in DataInfo)
                {
                    //if (index > 8) break;

                    if (fd.DataType == DataType.Int)
                    {
                        row["Data" + index] = dr[fd.ColumnName];
                    }
                    else if (fd.DataType == DataType.Double)
                    {
                        row["Data" + index] = _round(dr[fd.ColumnName].ToDouble(), fd.Precision);
                    }
                    else if (fd.DataType == DataType.EDouble)
                    {
                        row["Data" + index] = dr[fd.ColumnName].ToDouble().ScientificNotation(fd.Precision);
                    }
                    else if (fd.DataType == DataType.DateTime)
                    {
                        row["Data" + index] = Convert.ToDateTime(dr[fd.ColumnName]).ToString("yyyy-MM-dd HH:mm:ss");
                    }
                    else
                    {
                        row["Data" + index] = dr[fd.ColumnName].ToString();
                    }

                    index++;
                }

                dt.Rows.Add(row);
            }
        }

        private void _initInfo()
        {
            var sda = new SqliteDataAccess(_files.Last());
            if (_languages.Count == 0)
            {
                var lans = sda.GetLanguages();
                foreach (var l in lans)
                {
                    _languages.Add(l.LanguageId, l.Text);
                }
            }

            Id = sda.GetTestId();
            ParamInfo = sda.GetParameters();
            var name = ParamInfo.Single(d => d.DataNo == TypeId).ColumnName;
            var tmp = sda.GetOneParamValue(name).ToInt();
            //if (tmp != _type)
            {
                AddInputs.Clear();
                var pi = ParamInfo.SingleOrDefault(p => p.DataNo == 10034);
                if (pi != null) ParamInfo.Remove(pi);
                ResultInfo = sda.GetResults();
                pi = ResultInfo.SingleOrDefault(p => p.DataNo == 10034);
                if (pi != null) ResultInfo.Remove(pi);
                DataInfo = sda.GetData();
                DataSelected.Clear();
                _type = tmp;
                if (_cfgs.ContainsKey(_type))
                {
                    var cfg = _cfgs[_type];
                    if (!string.IsNullOrEmpty(cfg.Param))
                    {
                        ParamSelected = JsonConvert.DeserializeObject<List<SelectedData>>(cfg.Param);
                        if (ParamSelected.Count == 0)
                        {

                        }
                    }
                    else
                    {
                        ParamSelected.Clear();
                        foreach (var fd in ParamInfo)
                        {
                            ParamSelected.Add(new SelectedData { Id = fd.DataNo });
                        }
                    }
                    if (!string.IsNullOrEmpty(cfg.Result))
                    {
                        ResultSelected = JsonConvert.DeserializeObject<List<SelectedData>>(cfg.Result);
                        if (ResultSelected.Count == 0)
                        {
                            foreach (var fd in ResultInfo)
                            {
                                if (fd.DataNo == 10034) continue;
                                ResultSelected.Add(new SelectedData { Id = fd.DataNo });
                            }

                        }
                    }
                    if (!string.IsNullOrEmpty(cfg.DataList))
                    {
                        DataSelected = JsonConvert.DeserializeObject<List<SelectedData>>(cfg.DataList);
                    }
                    //if (!string.IsNullOrEmpty(cfg.DataCurve))
                    //{
                    //    Curves = JsonConvert.DeserializeObject<List<Curve>>(cfg.DataCurve);
                    //}
                    foreach (var ps in ParamSelected)
                    {
                        if (ParamInfo.All(d => d.DataNo != ps.Id))
                        {
                            AddInputs.Add(ps.Id, "");
                            ParamInfo.Add(new FullData
                            {
                                DataNo = ps.Id,
                                Text = ps.Text,
                                Value = "",
                                ColumnName = ""
                            });
                        }
                    }
                    foreach (var ps in ResultSelected)
                    {
                        if (ResultInfo.All(d => d.DataNo != ps.Id))
                        {
                            AddInputs.Add(ps.Id, "");
                            ResultInfo.Add(new FullData
                            {
                                DataNo = ps.Id,
                                Text = ps.Text,
                                Value = "",
                                ColumnName = ""
                            });
                        }
                    }
                }
                else
                {
                    ParamSelected.Clear();
                    foreach (var fd in ParamInfo)
                    {
                        ParamSelected.Add(new SelectedData { Id = fd.DataNo });
                    }
                    ResultSelected.Clear();
                    foreach (var fd in ResultInfo)
                    {
                        if (fd.DataNo == 10034) continue;
                        ResultSelected.Add(new SelectedData { Id = fd.DataNo });
                    }
                }
            }

            if (_cfgs.ContainsKey(_type))
            {
                var cfg = _cfgs[_type];
                if (!string.IsNullOrEmpty(cfg.DataCurve))
                {
                    Curves = JsonConvert.DeserializeObject<List<Curve>>(cfg.DataCurve);
                }
            }


        }

        private string _round(double d, int p)
        {
            string format = "0";
            if (p > 0)
            {
                for (int j = 0; j < p; j++)
                {
                    format += "0";
                }
                format = format.Insert(1, ".");
            }
            //return Math.Round(value, digits).ToString();
            return d.ToString(format);
        }

        public Stream CreateReportStream(string path)
        {
            var s = new MemoryStream();
            var xml = XDocument.Load(path);
            _lastTop = 4.94271;
            //找到ReportItems节点
            var report = xml.FirstNode as XContainer;
            var items = report?.Nodes().ToArray()[3] as XElement;
            var reportSection = items?.FirstNode as XContainer;
            var body = reportSection?.FirstNode as XContainer;
            var reportItems = body?.FirstNode as XContainer;

            if (reportItems != null)
            {
                _getCurves(reportItems);
                if (DataSelected.Count > 0 && _source != null && _source.Tables.Count >= 2 && _source.Tables[1].Rows.Count > 0)
                {
                    var ln = reportItems.LastNode;
                    ln.AddAfterSelf(XElement.Parse(_getDataListName()));
                    ln = reportItems.LastNode;
                    ln.AddAfterSelf(XElement.Parse(_getDataListTable()));
                }
            }



            //xml.Save("123.rdlc");
            xml.Save(s);
            s.Position = 0;
            return s;
        }

        private string _getDataListName()
        {
            var xml = new StringBuilder("<Textbox  xmlns=\"http://schemas.microsoft.com/sqlserver/reporting/2016/01/reportdefinition\"");
            xml.Append(" xmlns:rd=\"http://schemas.microsoft.com/SQLServer/reporting/reportdesigner\" Name = \"TxtDataListName\">");
            xml.Append("<CanGrow>true</CanGrow>");
            xml.Append("<KeepTogether>true</KeepTogether>");
            xml.Append("<Paragraphs><Paragraph><TextRuns><TextRun>");
            xml.Append("<Value>= First(Fields!DateList.Value, \"RI\")</Value>");
            //xml.Append("<Style/>");
            xml.Append("<Style>");
            xml.Append("<FontFamily>宋体</FontFamily>");
            xml.Append("<FontWeight>Bold</FontWeight>");
            xml.Append("</Style>");
            xml.Append("</TextRun></TextRuns><Style/></Paragraph></Paragraphs>");
            xml.Append("<rd:DefaultName>Textbox10</rd:DefaultName>");
            xml.Append("<Top>").Append(_lastTop).Append("cm</Top>");
            xml.Append("<Left>0.11305cm</Left>");
            xml.Append("<Height>0.6cm</Height>");
            xml.Append("<Width>5.38396cm</Width>");
            xml.Append("<ZIndex>6</ZIndex>");
            xml.Append("<Style><Border><Style>None</Style>");
            xml.Append("</Border>");
            xml.Append("<PaddingLeft>0pt</PaddingLeft>");
            xml.Append("<PaddingRight>0pt</PaddingRight>");
            xml.Append("<PaddingTop>0pt</PaddingTop>");
            xml.Append("<PaddingBottom>0pt</PaddingBottom>");
            xml.Append("</Style>");
            xml.Append("</Textbox>");
            _lastTop += 0.6;
            return xml.ToString();





        }

        private string _getDataListTable()
        {
            var xml = new StringBuilder("<Tablix  xmlns=\"http://schemas.microsoft.com/sqlserver/reporting/2016/01/reportdefinition\"");
            xml.Append(" xmlns:rd=\"http://schemas.microsoft.com/SQLServer/reporting/reportdesigner\" Name = \"TabDataList\">");
            var hw = 16.2204;
            var nw = 1.0;
            var c = DataSelected.Count;
            var aw = (hw - nw) / c;
            xml.Append("<TablixBody><TablixColumns>");
            xml.Append("<TablixColumn><Width>");
            xml.Append(nw);
            xml.Append("cm </Width></TablixColumn>");
            for (int i = 0; i < c; i++)
            {
                xml.Append("<TablixColumn><Width>");
                xml.Append(aw);
                xml.Append("cm </Width></TablixColumn>");
            }
            xml.Append("</TablixColumns>");
            xml.Append("<TablixRows><TablixRow><Height> 0.6cm </Height><TablixCells>");
            #region 表头
            xml.Append("<TablixCell>");
            xml.Append("<CellContents>");
            xml.Append("<Textbox Name = \"Textbox16\">");
            xml.Append("<CanGrow>true</CanGrow>");
            xml.Append("<KeepTogether>true</KeepTogether>");
            xml.Append("<Paragraphs>");
            xml.Append("<Paragraph>");
            xml.Append("<TextRuns>");
            xml.Append("<TextRun>");
            xml.Append("<Value>No.</Value>");
            xml.Append("<Style>");
            xml.Append("<FontFamily>宋体</FontFamily>");
            xml.Append("</Style>");
            xml.Append("</TextRun>");
            xml.Append("</TextRuns>");
            xml.Append("<Style/>");
            xml.Append("</Paragraph>");
            xml.Append("</Paragraphs>");
            xml.Append("<rd:DefaultName>Textbox16</rd:DefaultName>");
            xml.Append("<Style>");
            xml.Append("<Border>");
            xml.Append("<Style>None</Style>");
            xml.Append("</Border>");
            xml.Append("<PaddingLeft>0pt</PaddingLeft>");
            xml.Append("<PaddingRight>0pt</PaddingRight>");
            xml.Append("<PaddingTop>0pt</PaddingTop>");
            xml.Append("<PaddingBottom>0pt</PaddingBottom>");
            xml.Append("</Style>");
            xml.Append("</Textbox>");
            xml.Append("</CellContents>");
            xml.Append("</TablixCell>");
            foreach (var ds in DataSelected)
            {
                var fd = DataInfo.Single(d => d.DataNo == ds.Id);
                xml.Append("<TablixCell>");
                xml.Append("<CellContents>");
                xml.Append("<Textbox Name = \"TextDln");
                xml.Append(fd.DataNo);
                xml.Append("\">");
                xml.Append("<CanGrow>true</CanGrow>");
                xml.Append("<KeepTogether>true</KeepTogether>");
                xml.Append("<Paragraphs>");
                xml.Append("<Paragraph>");
                xml.Append("<TextRuns>");
                xml.Append("<TextRun>");
                var str = fd.Text;
                if (!string.IsNullOrEmpty(fd.Unit) && fd.Unit != "null")
                {
                    str += " (" + fd.Unit + ")";
                }
                xml.Append("<Value>");
                xml.Append(str);
                xml.Append("</Value>");
                xml.Append("<Style>");
                xml.Append("<FontFamily>宋体</FontFamily>");
                xml.Append("</Style>");
                //xml.Append("<Style/>");
                xml.Append("</TextRun>");
                xml.Append("</TextRuns>");
                xml.Append("<Style/>");
                xml.Append("</Paragraph>");
                xml.Append("</Paragraphs>");
                xml.Append("<rd:DefaultName>TextDln");
                xml.Append(fd.DataNo);
                xml.Append("</rd:DefaultName>");
                xml.Append("<Style>");
                xml.Append("<Border>");
                xml.Append("<Style>None</Style>");
                xml.Append("</Border>");
                xml.Append("<PaddingLeft>0pt</PaddingLeft>");
                xml.Append("<PaddingRight>0pt</PaddingRight>");
                xml.Append("<PaddingTop>0pt</PaddingTop>");
                xml.Append("<PaddingBottom>0pt</PaddingBottom>");
                xml.Append("</Style>");
                xml.Append("</Textbox>");
                xml.Append("</CellContents>");
                xml.Append("</TablixCell>");
            }
            #endregion
            xml.Append("</TablixCells>");
            xml.Append("</TablixRow>");
            xml.Append("<TablixRow>");
            xml.Append("<Height>0.4cm</Height>");
            xml.Append("<TablixCells>");
            #region 表体
            xml.Append("<TablixCell>");
            xml.Append("<CellContents>");
            xml.Append("<Textbox Name = \"TextNo\">");
            xml.Append("<CanGrow>true</CanGrow>");
            xml.Append("<KeepTogether>true</KeepTogether>");
            xml.Append("<Paragraphs>");
            xml.Append("<Paragraph>");
            xml.Append("<TextRuns>");
            xml.Append("<TextRun>");
            xml.Append("<Value>=RowNumber(nothing) </Value>");
            xml.Append("<Style/>");
            xml.Append("</TextRun>");
            xml.Append("</TextRuns>");
            xml.Append(" <Style><TextAlign>Left</TextAlign></Style> ");
            xml.Append("</Paragraph>");
            xml.Append("</Paragraphs>");
            xml.Append("<rd:DefaultName>Textbox17</rd:DefaultName>");
            xml.Append("<Style>");
            xml.Append("<Border>");
            xml.Append("<Style>None</Style>");
            xml.Append("</Border>");
            xml.Append("<PaddingLeft>0pt</PaddingLeft>");
            xml.Append("<PaddingRight>0pt</PaddingRight>");
            xml.Append("<PaddingTop>0pt</PaddingTop>");
            xml.Append("<PaddingBottom>0pt</PaddingBottom>");
            xml.Append("</Style>");
            xml.Append("</Textbox>");
            xml.Append("</CellContents>");
            xml.Append("</TablixCell>");
            foreach (var ds in DataSelected)
            {
                var i = DataInfo.FindIndex(d => d.DataNo == ds.Id) + 1;
                xml.Append("<TablixCell>");
                xml.Append("<CellContents>");
                xml.Append("<Textbox Name = \"Data");
                xml.Append(i);
                xml.Append("\">");
                xml.Append("<CanGrow>true</CanGrow>");
                xml.Append("<KeepTogether>true</KeepTogether>");
                xml.Append("<Paragraphs>");
                xml.Append("<Paragraph>");
                xml.Append("<TextRuns>");
                xml.Append("<TextRun>");
                xml.Append("<Value>=Fields!Data");
                xml.Append(i);
                xml.Append(".Value</Value>");
                xml.Append("<Style/>");
                xml.Append("</TextRun>");
                xml.Append("</TextRuns>");
                xml.Append(" <Style><TextAlign>Left</TextAlign></Style>");
                xml.Append("</Paragraph>");
                xml.Append("</Paragraphs>");
                xml.Append("<rd:DefaultName>Data");
                xml.Append(i);
                xml.Append("</rd:DefaultName>");
                xml.Append("<Style>");
                xml.Append("<Border>");
                xml.Append("<Style>None</Style>");
                xml.Append("</Border>");
                xml.Append("<PaddingLeft>0pt</PaddingLeft>");
                xml.Append("<PaddingRight>0pt</PaddingRight>");
                xml.Append("<PaddingTop>0pt</PaddingTop>");
                xml.Append("<PaddingBottom>0pt</PaddingBottom>");
                xml.Append("</Style>");
                xml.Append("</Textbox>");
                xml.Append("</CellContents>");
                xml.Append("</TablixCell>");
            }
            #endregion
            xml.Append("</TablixCells>");
            xml.Append("</TablixRow>");
            xml.Append("</TablixRows>");
            xml.Append("</TablixBody>");
            xml.Append("<TablixColumnHierarchy>");
            xml.Append("<TablixMembers>");
            xml.Append("<TablixMember />");
            for (int i = 0; i < c; i++)
            {
                xml.Append("<TablixMember />");
            }
            xml.Append("</TablixMembers>");
            xml.Append("</TablixColumnHierarchy>");
            xml.Append("<TablixRowHierarchy>");
            xml.Append("<TablixMembers>");
            xml.Append("<TablixMember>");
            xml.Append("<KeepWithGroup>After</KeepWithGroup>");
            xml.Append("</TablixMember>");
            xml.Append("<TablixMember>");
            xml.Append("<Group Name=\"详细信息3\" />");
            xml.Append("</TablixMember>");
            xml.Append("</TablixMembers>");
            xml.Append("</TablixRowHierarchy>");
            xml.Append("<DataSetName>DL</DataSetName>");
            xml.Append("<Top>").Append(_lastTop).Append("cm</Top>");
            xml.Append("<Left>0.1261cm</Left>");
            xml.Append("<Height>1.2cm</Height>");
            xml.Append("<Width>10cm</Width>");
            xml.Append("<ZIndex>7</ZIndex>");
            xml.Append("<Style>");
            xml.Append("<Border>");
            xml.Append("<Style>None</Style>");
            xml.Append("</Border>");
            xml.Append("</Style>");
            xml.Append("</Tablix>");
            return xml.ToString();
        }

        private void _getCurves(XContainer node)
        {
            if (_source == null || _source.Tables.Count < 2 || _source.Tables[1].Rows.Count == 0) return;

            var index = 1;
            foreach (var curve in Curves)
            {
                var xi = DataInfo.FindIndex(d => d.DataNo == curve.X.Id) + 1;
                var xinfo = DataInfo.Single(d => d.DataNo == curve.X.Id);
                var yi1 = DataInfo.FindIndex(d => d.DataNo == curve.Y[0].Id) + 1;
                var yinfo1 = DataInfo.Single(d => d.DataNo == curve.Y[0].Id);
                var yi2 = -1;
                FullData yinfo2 = null;
                if (curve.Y.Count > 1)
                {
                    yi2 = DataInfo.FindIndex(d => d.DataNo == curve.Y[1].Id) + 1;
                    yinfo2 = DataInfo.Single(d => d.DataNo == curve.Y[1].Id);
                }
                var xml = new StringBuilder("<Chart Name=\"Chart").Append(index).Append("\"  xmlns=\"http://schemas.microsoft.com/sqlserver/reporting/2016/01/reportdefinition\" ");
                xml.Append(" xmlns:rd=\"http://schemas.microsoft.com/SQLServer/reporting/reportdesigner\">");
                #region X轴
                xml.Append("<ChartCategoryHierarchy>");
                xml.Append("<ChartMembers>");
                xml.Append("<ChartMember>");
                xml.Append("<Group Name=\"Chart").Append(index).Append("_CategoryGroup\">");
                xml.Append("<GroupExpressions>");
                xml.Append("<GroupExpression>=Fields!Data").Append(xi).Append(".Value</GroupExpression>");
                xml.Append("</GroupExpressions>");
                xml.Append("</Group>");
                xml.Append("<Label>=Fields!Data").Append(xi).Append(".Value</Label>");
                //xml.Append("<SortExpressions>");
                //xml.Append("<SortExpression>");
                //xml.Append("<Value>=Fields!Data").Append(xi).Append(".Value</Value>");
                //xml.Append("</SortExpression>");
                //xml.Append("</SortExpressions>");
                xml.Append("</ChartMember>");
                xml.Append("</ChartMembers>");
                xml.Append("</ChartCategoryHierarchy>");
                #endregion

                #region  Y轴
                xml.Append("<ChartSeriesHierarchy>");
                xml.Append("<ChartMembers>");
                xml.Append("<ChartMember>");
                xml.Append("<Label>Data").Append(yi1).Append("</Label>");
                xml.Append("</ChartMember>");
                if (yi2 > 0)
                {
                    xml.Append("<ChartMember>");
                    xml.Append("<Label>Data").Append(yi2).Append("</Label>");
                    xml.Append("</ChartMember>");
                }
                xml.Append("</ChartMembers>");
                xml.Append("</ChartSeriesHierarchy>");

                xml.Append("<ChartData>");
                xml.Append("<ChartSeriesCollection>");
                xml.Append("<ChartSeries Name=\"Data").Append(yi1).Append("\">");
                xml.Append("<ChartDataPoints>");
                xml.Append("<ChartDataPoint>");
                xml.Append("<ChartDataPointValues>");
                xml.Append("<Y>=Fields!Data").Append(yi1).Append(".Value</Y>");
                xml.Append("</ChartDataPointValues>");
                xml.Append("<ChartDataLabel>");
                xml.Append("<Style>");
                xml.Append("<Color>Red</Color>");
                xml.Append("</Style>");
                xml.Append("<UseValueAsLabel>true</UseValueAsLabel>");
                if (curve.IsDrawPoint)
                {
                    xml.Append("<Visible>true</Visible>");
                }
                xml.Append("</ChartDataLabel>");
                xml.Append("<Style>");
                xml.Append("<Border>");
                xml.Append("<Color>Red</Color>");
                xml.Append("</Border>");
                xml.Append("<Color>Red</Color>");
                xml.Append("</Style>");
                xml.Append("<ChartMarker>");
                if (curve.IsDrawPoint)
                {
                    xml.Append("<Type>Auto</Type>");
                }
                xml.Append("<Style>");
                xml.Append("<Border>");
                xml.Append("<Color>Red</Color>");
                xml.Append("</Border>");
                xml.Append("</Style>");
                xml.Append("</ChartMarker>");
                xml.Append("<DataElementOutput>Output</DataElementOutput>");
                xml.Append("</ChartDataPoint>");
                xml.Append("</ChartDataPoints>");
                xml.Append("<Type>Line</Type>");
                xml.Append("<Style/>");
                xml.Append("<ChartEmptyPoints>");
                xml.Append("<Style/>");
                xml.Append("<ChartMarker>");
                xml.Append("<Style/>");
                xml.Append("</ChartMarker>");
                xml.Append("<ChartDataLabel>");
                xml.Append("<Style/>");
                xml.Append("</ChartDataLabel>");
                xml.Append("</ChartEmptyPoints>");
                xml.Append("<ChartItemInLegend>");
                xml.Append("<LegendText>").Append($"{yinfo1.Text}({yinfo1.Unit})").Append("</LegendText>");
                xml.Append("</ChartItemInLegend>");
                xml.Append("<ValueAxisName>Primary</ValueAxisName>");
                xml.Append("<CategoryAxisName>Primary</CategoryAxisName>");
                xml.Append("<ChartSmartLabel>");
                xml.Append("<CalloutLineColor>Black</CalloutLineColor>");
                xml.Append("<MinMovingDistance>0pt</MinMovingDistance>");
                xml.Append("</ChartSmartLabel>");
                xml.Append("</ChartSeries>");
                if (yi2 > 0)
                {
                    xml.Append("<ChartSeries Name=\"Data").Append(yi2).Append("\">");
                    xml.Append("<ChartDataPoints>");
                    xml.Append("<ChartDataPoint>");
                    xml.Append("<ChartDataPointValues>");
                    xml.Append("<Y>=Fields!Data").Append(yi2).Append(".Value</Y>");
                    xml.Append("</ChartDataPointValues>");
                    xml.Append("<ChartDataLabel>");
                    xml.Append("<Style>");
                    xml.Append("<Color>Green</Color>");
                    xml.Append("</Style>");
                    xml.Append("<UseValueAsLabel>true</UseValueAsLabel>");
                    if (curve.IsDrawPoint)
                    {
                        xml.Append("<Visible>true</Visible>");
                    }
                    xml.Append("</ChartDataLabel>");
                    xml.Append("<Style>");
                    xml.Append("<Border>");
                    xml.Append("<Color>Green</Color>");
                    xml.Append("</Border>");
                    xml.Append("<Color>Green</Color>");
                    xml.Append("</Style>");
                    xml.Append("<ChartMarker>");
                    if (curve.IsDrawPoint)
                    {
                        xml.Append("<Type>Auto</Type>");
                    }
                    xml.Append("<Style/>");
                    xml.Append("</ChartMarker>");
                    xml.Append("<DataElementOutput>Output</DataElementOutput>");
                    xml.Append("</ChartDataPoint>");
                    xml.Append("</ChartDataPoints>");
                    xml.Append("<Type>Line</Type>");
                    xml.Append("<Style/>");
                    xml.Append("<ChartEmptyPoints>");
                    xml.Append("<Style/>");
                    xml.Append("<ChartMarker>");
                    xml.Append("<Style/>");
                    xml.Append("</ChartMarker>");
                    xml.Append("<ChartDataLabel>");
                    xml.Append("<Style/>");
                    xml.Append("</ChartDataLabel>");
                    xml.Append("</ChartEmptyPoints>");
                    xml.Append("<ChartItemInLegend>");
                    xml.Append("<LegendText>").Append($"{yinfo2.Text}({yinfo2.Unit})").Append("</LegendText>");
                    xml.Append("</ChartItemInLegend>");
                    xml.Append("<ValueAxisName>Secondary</ValueAxisName>");
                    xml.Append("<CategoryAxisName>Primary</CategoryAxisName>");
                    xml.Append("<ChartSmartLabel>");
                    xml.Append("<CalloutLineColor>Black</CalloutLineColor>");
                    xml.Append("<MinMovingDistance>0pt</MinMovingDistance>");
                    xml.Append("</ChartSmartLabel>");
                    xml.Append("</ChartSeries>");
                }

                xml.Append("</ChartSeriesCollection>");
                xml.Append("</ChartData>");
                #endregion

                #region 曲线
                xml.Append("<ChartAreas>");
                xml.Append("<ChartArea Name=\"Default\">");
                xml.Append("<ChartCategoryAxes>");
                xml.Append("<ChartAxis Name=\"Primary\">");
                xml.Append("<Style>");
                xml.Append("<Border>");
                xml.Append("<Color>Gainsboro</Color>");
                xml.Append("<Style>None</Style>");
                xml.Append("</Border>");
                xml.Append("<FontSize>8pt</FontSize>");
                xml.Append("<Color>#5c5c5c</Color>");
                xml.Append("</Style>");
                xml.Append("<ChartAxisTitle>");
                var st = xinfo.Text;
                if (!string.IsNullOrEmpty(xinfo.Unit.Replace("null", ""))) st = $"{st}({xinfo.Unit})";
                xml.Append("<Caption>").Append(st).Append("</Caption>");
                xml.Append("<Style>");
                xml.Append("<FontSize>9pt</FontSize>");
                xml.Append("<Color>#5c5c5c</Color>");
                xml.Append("</Style>");
                xml.Append("</ChartAxisTitle>");
                xml.Append("<ChartMajorGridLines>");
                xml.Append("<Enabled>True</Enabled>");
                xml.Append("<Style>");
                xml.Append("<Border>");
                xml.Append("<Color>Gainsboro</Color>");
                xml.Append("</Border>");
                xml.Append("</Style>");
                xml.Append("</ChartMajorGridLines>");
                xml.Append("<ChartMinorGridLines>");
                xml.Append("<Style>");
                xml.Append("<Border>");
                xml.Append("<Color>Gainsboro</Color>");
                xml.Append("<Style>Dotted</Style>");
                xml.Append("</Border>");
                xml.Append("</Style>");
                xml.Append("</ChartMinorGridLines>");
                xml.Append("<ChartMajorTickMarks>");
                xml.Append("<Style>");
                xml.Append("<Border>");
                xml.Append("<Color>Gainsboro</Color>");
                xml.Append("<Style>None</Style>");
                xml.Append("</Border>");
                xml.Append("</Style>");
                xml.Append("</ChartMajorTickMarks>");
                xml.Append("<ChartMinorTickMarks>");
                xml.Append("<Style>");
                xml.Append("<Border>");
                xml.Append("<Color>Gainsboro</Color>");
                xml.Append("</Border>");
                xml.Append("</Style>");
                xml.Append("<Length>0.5</Length>");
                xml.Append("</ChartMinorTickMarks>");
                xml.Append("<CrossAt>NaN</CrossAt>");
                xml.Append("<Scalar>true</Scalar>");
                xml.Append("<Minimum>NaN</Minimum>");
                xml.Append("<Maximum>NaN</Maximum>");
                xml.Append("<ChartAxisScaleBreak>");
                xml.Append("<Style/>");
                xml.Append("</ChartAxisScaleBreak>");
                xml.Append("</ChartAxis>");
                xml.Append("<ChartAxis Name=\"Secondary\">");
                xml.Append("<Style>");
                xml.Append("<Border>");
                xml.Append("<Color>Gainsboro</Color>");
                xml.Append("<Style>None</Style>");
                xml.Append("</Border>");
                xml.Append("<FontSize>8pt</FontSize>");
                xml.Append("<Color>#5c5c5c</Color>");
                xml.Append("</Style>");
                xml.Append("<ChartAxisTitle>");
                xml.Append("<Caption/>");
                xml.Append("<Style>");
                xml.Append("<FontSize>9pt</FontSize>");
                xml.Append("<Color>#5c5c5c</Color>");
                xml.Append("</Style>");
                xml.Append("</ChartAxisTitle>");
                xml.Append("<ChartMajorGridLines>");
                xml.Append("<Enabled>False</Enabled>");
                xml.Append("<Style>");
                xml.Append("<Border>");
                xml.Append("<Color>Gainsboro</Color>");
                xml.Append("</Border>");
                xml.Append("</Style>");
                xml.Append("</ChartMajorGridLines>");
                xml.Append("<ChartMinorGridLines>");
                xml.Append("<Style>");
                xml.Append("<Border>");
                xml.Append("<Color>Gainsboro</Color>");
                xml.Append("<Style>Dotted</Style>");
                xml.Append("</Border>");
                xml.Append("</Style>");
                xml.Append("</ChartMinorGridLines>");
                xml.Append("<ChartMajorTickMarks>");
                xml.Append("<Style>");
                xml.Append("<Border>");
                xml.Append("<Color>Gainsboro</Color>");
                xml.Append("<Style>None</Style>");
                xml.Append("</Border>");
                xml.Append("</Style>");
                xml.Append("</ChartMajorTickMarks>");
                xml.Append("<ChartMinorTickMarks>");
                xml.Append("<Style>");
                xml.Append("<Border>");
                xml.Append("<Color>Gainsboro</Color>");
                xml.Append("</Border>");
                xml.Append("</Style>");
                xml.Append("<Length>0.5</Length>");
                xml.Append("</ChartMinorTickMarks>");
                xml.Append("<CrossAt>NaN</CrossAt>");
                xml.Append("<Location>Opposite</Location>");
                xml.Append("<Minimum>NaN</Minimum>");
                xml.Append("<Maximum>NaN</Maximum>");
                xml.Append("<ChartAxisScaleBreak>");
                xml.Append("<Style/>");
                xml.Append("</ChartAxisScaleBreak>");
                xml.Append("</ChartAxis>");
                xml.Append("</ChartCategoryAxes>");
                xml.Append("<ChartValueAxes>");
                xml.Append("<ChartAxis Name=\"Primary\">");
                xml.Append("<Style>");
                xml.Append("<Border>");
                xml.Append("<Color>DimGray</Color>");
                xml.Append("<Style>None</Style>");
                xml.Append("</Border>");
                xml.Append("<FontSize>8pt</FontSize>");
                xml.Append("<Color>Red</Color>");
                xml.Append("</Style>");
                xml.Append("<ChartAxisTitle>");
                xml.Append("<Caption/>");
                xml.Append("<Style>");
                xml.Append("<FontSize>9pt</FontSize>");
                xml.Append("<Color>#5c5c5c</Color>");
                xml.Append("</Style>");
                xml.Append("</ChartAxisTitle>");
                xml.Append("<ChartMajorGridLines>");
                xml.Append("<Style>");
                xml.Append("<Border>");
                xml.Append("<Color>Silver</Color>");
                xml.Append("</Border>");
                xml.Append("</Style>");
                xml.Append("</ChartMajorGridLines>");
                xml.Append("<ChartMinorGridLines>");
                xml.Append("<Style>");
                xml.Append("<Border>");
                xml.Append("<Color>Gainsboro</Color>");
                xml.Append("<Style>Dotted</Style>");
                xml.Append("</Border>");
                xml.Append("</Style>");
                xml.Append("</ChartMinorGridLines>");
                xml.Append("<ChartMajorTickMarks>");
                xml.Append("<Style>");
                xml.Append("<Border>");
                xml.Append("<Color>DimGray</Color>");
                xml.Append("<Style>Solid</Style>");
                xml.Append("</Border>");
                xml.Append("</Style>");
                xml.Append("</ChartMajorTickMarks>");
                xml.Append("<ChartMinorTickMarks>");
                xml.Append("<Style>");
                xml.Append("<Border>");
                xml.Append("<Color>Gainsboro</Color>");
                xml.Append("</Border>");
                xml.Append("</Style>");
                xml.Append("<Length>0.5</Length>");
                xml.Append("</ChartMinorTickMarks>");
                xml.Append("<CrossAt>NaN</CrossAt>");
                xml.Append("<Minimum>NaN</Minimum>");
                xml.Append("<Maximum>NaN</Maximum>");
                xml.Append("<ChartAxisScaleBreak>");
                xml.Append("<Style/>");
                xml.Append("</ChartAxisScaleBreak>");
                xml.Append("</ChartAxis>");
                xml.Append("<ChartAxis Name=\"Secondary\">");
                xml.Append("<Style>");
                xml.Append("<Border>");
                xml.Append("<Color>Silver</Color>");
                xml.Append("<Style>None</Style>");
                xml.Append("</Border>");
                xml.Append("<FontSize>8pt</FontSize>");
                xml.Append("<Color>Green</Color>");
                xml.Append("</Style>");
                xml.Append("<ChartAxisTitle>");
                xml.Append("<Caption/>");
                xml.Append("<Style>");
                xml.Append("<FontSize>9pt</FontSize>");
                xml.Append("<Color>#5c5c5c</Color>");
                xml.Append("</Style>");
                xml.Append("</ChartAxisTitle>");
                xml.Append("<ChartMajorGridLines>");
                xml.Append("<Style>");
                xml.Append("<Border>");
                xml.Append("<Color>Silver</Color>");
                xml.Append("<Style>Dashed</Style>");
                xml.Append("</Border>");
                xml.Append("</Style>");
                xml.Append("</ChartMajorGridLines>");
                xml.Append("<ChartMinorGridLines>");
                xml.Append("<Style>");
                xml.Append("<Border>");
                xml.Append("<Color>Gainsboro</Color>");
                xml.Append("<Style>Dotted</Style>");
                xml.Append("</Border>");
                xml.Append("</Style>");
                xml.Append("</ChartMinorGridLines>");
                xml.Append("<ChartMajorTickMarks>");
                xml.Append("<Style>");
                xml.Append("<Border>");
                xml.Append("<Color>Silver</Color>");
                xml.Append("<Style>Dashed</Style>");
                xml.Append("</Border>");
                xml.Append("</Style>");
                xml.Append("</ChartMajorTickMarks>");
                xml.Append("<ChartMinorTickMarks>");
                xml.Append("<Style>");
                xml.Append("<Border>");
                xml.Append("<Color>Gainsboro</Color>");
                xml.Append("</Border>");
                xml.Append("</Style>");
                xml.Append("<Length>0.5</Length>");
                xml.Append("</ChartMinorTickMarks>");
                xml.Append("<CrossAt>NaN</CrossAt>");
                xml.Append("<Location>Opposite</Location>");
                xml.Append("<Minimum>NaN</Minimum>");
                xml.Append("<Maximum>NaN</Maximum>");
                xml.Append("<ChartAxisScaleBreak>");
                xml.Append("<Style/>");
                xml.Append("</ChartAxisScaleBreak>");
                xml.Append("</ChartAxis>");
                xml.Append("</ChartValueAxes>");
                xml.Append("<Style>");
                xml.Append("<Border>");
                xml.Append("<Style>Solid</Style>");
                xml.Append("</Border>");
                xml.Append("<BackgroundColor>#00ffffff</BackgroundColor>");
                xml.Append("<BackgroundGradientType>None</BackgroundGradientType>");
                xml.Append("</Style>");
                xml.Append("</ChartArea>");
                xml.Append("</ChartAreas>");
                #endregion

                #region 图例
                xml.Append("<ChartLegends>");
                xml.Append("<ChartLegend Name=\"Default\">");
                xml.Append("<Style>");
                xml.Append("<BackgroundGradientType>None</BackgroundGradientType>");
                xml.Append("<FontSize>8pt</FontSize>");
                xml.Append("</Style>");
                xml.Append("<Position>TopLeft</Position>");
                xml.Append("<ChartLegendTitle>");
                xml.Append("<Caption/>");
                xml.Append("<Style>");
                xml.Append("<FontSize>8pt</FontSize>");
                xml.Append("<FontWeight>Bold</FontWeight>");
                xml.Append("<TextAlign>Center</TextAlign>");
                xml.Append("</Style>");
                xml.Append("</ChartLegendTitle>");
                xml.Append("<HeaderSeparatorColor>Black</HeaderSeparatorColor>");
                xml.Append("<ColumnSeparatorColor>Black</ColumnSeparatorColor>");
                xml.Append("</ChartLegend>");
                xml.Append("</ChartLegends>");
                #endregion

                #region 标题
                xml.Append("<ChartTitles>");
                xml.Append("<ChartTitle Name=\"Default\">");
                var title = string.IsNullOrEmpty(curve.Title) ? string.Format(ReportCommon.GetLan.GetLanguageValue("CurveNameSeq"), index) : curve.Title;
                xml.Append("<Caption>").Append(title).Append("</Caption>");
                xml.Append("<Style>");
                xml.Append("<BackgroundGradientType>None</BackgroundGradientType>");
                xml.Append("<FontSize>9pt</FontSize>");
                xml.Append("<FontWeight>Normal</FontWeight>");
                xml.Append("<TextAlign>Left</TextAlign>");
                xml.Append("<VerticalAlign>Top</VerticalAlign>");
                xml.Append("</Style>");
                xml.Append("</ChartTitle>");
                xml.Append("</ChartTitles>");
                #endregion

                #region 曲线公共属性
                xml.Append("<Palette>Pacific</Palette>");
                xml.Append("<ChartBorderSkin>");
                xml.Append("<Style>");
                xml.Append("<BackgroundColor>Black</BackgroundColor>");
                xml.Append("<BackgroundGradientType>None</BackgroundGradientType>");
                xml.Append("<Color>White</Color>");
                xml.Append("</Style>");
                xml.Append("</ChartBorderSkin>");
                xml.Append("<ChartNoDataMessage Name=\"NoDataMessage\">");
                xml.Append("<Caption>NoDatas</Caption>");
                xml.Append("<Style>");
                xml.Append("<BackgroundGradientType>None</BackgroundGradientType>");
                xml.Append("<FontWeight>Bold</FontWeight>");
                xml.Append("<TextAlign>General</TextAlign>");
                xml.Append("<VerticalAlign>Top</VerticalAlign>");
                xml.Append("</Style>");
                xml.Append("</ChartNoDataMessage>");
                xml.Append("<DataSetName>DL</DataSetName>");
                xml.Append("<Top>").Append(_lastTop).Append("cm</Top>");
                xml.Append("<Left>0.1cm</Left>");
                xml.Append("<Height>").Append(CurveHeight).Append("cm</Height>");
                xml.Append("<Width>16.21122cm</Width>");
                xml.Append("<ZIndex>5</ZIndex>");
                xml.Append("<Style>");
                xml.Append("<Border>");
                xml.Append("<Color>Black</Color>");
                xml.Append("<Style>None</Style>");
                xml.Append("</Border>");
                xml.Append("<BackgroundColor>White</BackgroundColor>");
                xml.Append("<BackgroundGradientType>None</BackgroundGradientType>");
                xml.Append("</Style>");
                xml.Append("</Chart>");

                _lastTop += CurveHeight;
                #endregion
                var ln = node.LastNode;
                ln.AddAfterSelf(XElement.Parse(xml.ToString()));
                index++;
            }
        }
    }
}



